/*
 *
 * Copyright(c) 2018-2019 chj <1019487871@qq.com>
 * QQ: 1019487871
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 *
 */
#include "los.h"
#include "../component/fundation/string/los_string.h"

char *
los_strcpy(char * dest, const char * src)
{
    char * tmp = dest;

    while ((*dest++ = *src++) != '\0');
    return tmp;
}

void *
los_memchr(const void * s, int c, size_t n)
{
    const unsigned char *p = s;

    while (n-- != 0)
    {
        if ((unsigned char)c == *p++)
        {
            return (void *)(p - 1);
        }
    }
    return NULL;
}

void *
los_memcpy(void * dest, const void * src, size_t len)
{
    char * tmp = dest;
    const char * s = src;

    while (len--)
        *tmp++ = *s++;
    return dest;
}

int
los_memcmp(const void * s1, const void * s2, size_t n)
{
    const unsigned char *su1, *su2;
    int res = 0;

    for (su1 = s1, su2 = s2; 0 < n; ++su1, ++su2, n--)
        if ((res = *su1 - *su2) != 0)
            break;
    return res;
}

void *
los_memscan(void * addr, int c, size_t size)
{
    unsigned char * p = addr;

    while (size)
    {
        if (*p == c)
            return (void *)p;
        p++;
        size--;
    }
    return (void *)p;
}

void *
los_memset(void * s, int c, size_t n)
{
    char * xs = s;

    while (n--)
        *xs++ = c;

    return s;
}

char *
los_strcat(char * dest, const char * src)
{
    char * tmp = dest;

    while (*dest)
        dest++;
    while ((*dest++ = *src++) != '\0');

    return tmp;
}

char *
los_strchr(const char * s, int c)
{
    for (; *s != (char)c; ++s)
        if (*s == '\0')
            return NULL;
    return (char *)s;
}

int
los_strcmp(const char * s1, const char * s2)
{
    int res;

    while (1)
    {
        if ((res = *s1 - *s2++) != 0 || !*s1++)
            break;
    }
    return res;
}

size_t
los_strcspn(const char * s, const char * reject)
{
    const char * p;
    const char * r;
    size_t count = 0;

    for (p = s; *p != '\0'; ++p)
    {
        for (r = reject; *r != '\0'; ++r)
        {
            if (*p == *r)
                return count;
        }
        ++count;
    }
    return count;
}

char *
los_strncat(char * dest, const char * src, size_t n)
{
    char * tmp = dest;

    if (n)
    {
        while (*dest)
            dest++;
        while ((*dest++ = *src++) != 0)
        {
            if (--n == 0)
            {
                *dest = '\0';
                break;
            }
        }
    }
    return tmp;
}

char *
los_strnchr(const char * s, size_t n, int c)
{
    for (; n-- && *s != '\0'; ++s)
        if (*s == (char)c)
            return (char *)s;
    return NULL;
}

int
los_strncmp(const char * s1, const char * s2, size_t n)
{
    int __res = 0;

    while (n)
    {
        if ((__res = *s1 - *s2++) != 0 || !*s1++)
            break;
        n--;
    }
    return __res;
}

char *
los_strncpy(char * dest, const char * src, size_t n)
{
    char * tmp = dest;

    while (n)
    {
        if ((*tmp = *src) != 0)
            src++;
        tmp++;
        n--;
    }
    return dest;
}

size_t
los_strnlen(const char * s, size_t n)
{
    const char * sc;

    for (sc = s; n-- && *sc != '\0'; ++sc);
    return sc - s;
}

size_t
los_strlen(const char * s)
{
    const char * sc;

    for (sc = s; *sc != '\0'; ++sc);
    return sc - s;
}

char *
los_strnstr(const char * s1, const char * s2, size_t n)
{
    size_t l2;

    l2 = los_strlen(s2);
    if (!l2)
        return (char *)s1;

    while (n >= l2)
    {
        n--;
        if (!los_memcmp(s1, s2, l2))
            return (char *)s1;
        s1++;
    }

    return NULL;
}

char *
los_strpbrk(const char * s1, const char * s2)
{
    const char * sc1, * sc2;

    for (sc1 = s1; *sc1 != '\0'; ++sc1)
    {
        for (sc2 = s2; *sc2 != '\0'; ++sc2)
        {
            if (*sc1 == *sc2)
                return (char *)sc1;
        }
    }

    return NULL;
}

char *
los_strrchr(const char * s, int c)
{
    const char * p = s + los_strlen(s);

    do {
       if (*p == (char)c)
           return (char *)p;
    } while (--p >= s);

    return NULL;
}

size_t
los_strspn(const char * s, const char * accept)
{
    const char * p;
    const char * a;
    size_t count = 0;

    for (p = s; *p != '\0'; ++p)
    {
        for (a = accept; *a != '\0'; ++a)
        {
            if (*p == *a)
                break;
        }
        if (*a == '\0')
            return count;
        ++count;
    }
    return count;
}

char *
los_strstr(const char * s1, const char * s2)
{
    size_t l1, l2;

    l2 = los_strlen(s2);
    if (!l2)
        return (char *)s1;

    l1 = los_strlen(s1);
    while (l1 >= l2)
    {
        l1--;
        if (!los_memcmp(s1, s2, l2))
            return (char *)s1;
        s1++;
    }

    return NULL;
}


